/*******************************************************************************
 * FilePath    : /Software/Examples_Adv_MS1658/adv_app_TxRx/Src/BSP/UART.c
 * Version     : 1.0
 * Brief       : 
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-03-24 15:42:28
 * LastEditors : AndrewHu
 * LastEditTime: 2021-08-24 17:13:30
 * Description : 
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define UARTx UART0
#define BAUDRATE 115200
#define UARTx_TX_PORT GPIOA
#define UARTx_TX_PIN GPIO_PIN_2
#define UARTx_RX_PORT GPIOD
#define UARTx_RX_PIN GPIO_PIN_3
#define UARTx_TX_ALTERNATE_AFn GPIO_AF5_UART0_TXD
#define UARTx_RX_ALTERNATE_AFn GPIO_AF5_UART0_RXD
#define UARTx_IRQn UART0_IRQn

#define __HAL_RCC_UARTx_CLK_ENABLE() __HAL_RCC_UART0_CLK_ENABLE()
#define __HAL_RCC_UARTx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()

#define MAX_SIZE 200
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static UART_HandleTypeDef UART_InitStruct = {0};

static u8 txBuf[MAX_SIZE], rxBuf[MAX_SIZE];
static u8 txCount = 0, rxCount = 0; //待发送、接收待取出数据的Index
static u8 txLen = 0, rxLen = 0;     //已发送、接收并取出数据的Index
static u8 rxTimeOut = 0;            //接收超时，判断串口数据是否发送完成
static u8 txEn = 0;                 //发送使能标志
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : UART_GPIO_Init
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 17:09:29
 * Description : 
 ******************************************************************************/
static void UART_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOD_CLK_ENABLE();

    //串口通讯，TX-PA2,RX-PD3
    GPIO_InitStruct.Pin = UARTx_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF;
    GPIO_InitStruct.OpenDrain = GPIO_PUSHPULL;
    GPIO_InitStruct.Debounce.Enable = GPIO_DEBOUNCE_DISABLE;
    GPIO_InitStruct.SlewRate = GPIO_SLEW_RATE_HIGH;
    GPIO_InitStruct.DrvStrength = GPIO_DRV_STRENGTH_HIGH;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Alternate = UARTx_RX_ALTERNATE_AFn;
    HAL_GPIO_Init(UARTx_RX_PORT, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = UARTx_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF;
    GPIO_InitStruct.Alternate = UARTx_TX_ALTERNATE_AFn;
    HAL_GPIO_Init(UARTx_TX_PORT, &GPIO_InitStruct);
}
/*******************************************************************************
 * Function    : Uart_Init
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 16:28:55
 * Description : 串口初始化
 ******************************************************************************/
void Uart_Init(void)
{
    UART_GPIO_Init();

    __HAL_RCC_UARTx_CLK_ENABLE();

    UART_InitStruct.Instance = UARTx;
    UART_InitStruct.Init.BaudRate = BAUDRATE;
    UART_InitStruct.Init.BaudDouble = UART_BAUDDOUBLE_ENABLE;
    UART_InitStruct.Init.WordLength = UART_WORDLENGTH_8B;
    UART_InitStruct.Init.Parity = UART_PARITY_NONE;
    UART_InitStruct.Init.Mode = UART_MODE_TX_RX;
    HAL_UART_Init(&UART_InitStruct);

    //HAL_UART_Transmit_IT(&UART_InitStruct, ucSendData, sizeof(ucSendData));
    //HAL_UART_Receive_IT(&UART_InitStruct, ucReceiveData, sizeof(ucReceiveData));
    UART_InitStruct.Instance->SCON |= UART_INTSR_RI | UART_INTSR_TI;
    HAL_NVIC_EnableIRQ(UARTx_IRQn);
}
/*******************************************************************************
 * Function    : UART0_INT_Callback
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 18:10:54
 * Description : 串口中断
 ******************************************************************************/
void UART0_INT_Callback(void)
{
    if ((UART_InitStruct.Instance->INTSR & UART_INTSR_RI) == UART_INTSR_RI) //串口接收中断
    {
        UART_InitStruct.Instance->INTCLR |= UART_INTCLR_RICLR_Msk;
        rxBuf[rxCount] = UART_InitStruct.Instance->SBUF;
        rxCount++; //Index add
        if (rxCount >= MAX_SIZE)
            rxCount = 0;
        rxTimeOut = 0x00;
    }
    else if ((UART_InitStruct.Instance->INTSR & UART_INTSR_TI) == UART_INTSR_TI) //串口发送中断
    {
        UART_InitStruct.Instance->INTCLR |= UART_INTCLR_TICLR_Msk;
        if (txLen != txCount)
        {
            UART_InitStruct.Instance->SBUF = txBuf[txLen];
            txLen++; //Index add
            if (txLen >= MAX_SIZE)
                txLen = 0;
        }
        else
        {
            txEn = 0; //发送完成
        }
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Byte
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 18:28:52
 * Description : 串口发送一个字节
 ******************************************************************************/
void Uart_Send_Byte(u8 data)
{
    txBuf[txCount] = data;
    txCount++;
    if (txCount >= MAX_SIZE)
        txCount = 0x00;
}
/*******************************************************************************
 * Function    : Uart_Send_Byte2Ascii
 * Brief       : 
 * Parameter   : {u8} data-待发送数据
 * Returns     : 
 * Date        : 2020-03-24 18:30:09
 * Description : 串口发送一个字节（转换成ASCII）
 ******************************************************************************/
void Uart_Send_Byte2Ascii(u8 data)
{
    Uart_Send_Byte(AHL_Data_Hex2Ascii_4bit(data >> 4));
    Uart_Send_Byte(AHL_Data_Hex2Ascii_4bit(data));
}
/*******************************************************************************
 * Function    : Uart_Send_Array
 * Brief       : 
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Returns     : 
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（原始数据）
 ******************************************************************************/
void Uart_Send_Array(u8 *data, u8 len)
{
    u8 i;
    for (i = 0; i < len; i++)
    {
        Uart_Send_Byte(data[i]);
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Array_R
 * Brief       : 
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Returns     : 
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（原始数据），倒序
 ******************************************************************************/
void Uart_Send_Array_R(u8 *data, u8 len)
{
    u8 i;
    for (i = len; i != 0; i--)
    {
        Uart_Send_Byte(data[i - 1]);
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Array2Ascii
 * Brief       : 
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Parameter   : {u8} space-是否空格做间隔
 * Returns     : 
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（转成ASCII）
 ******************************************************************************/
void Uart_Send_Array2Ascii(u8 *data, u8 len, u8 space)
{
    u8 i;
    for (i = 0; i < len; i++)
    {
        Uart_Send_Byte2Ascii(data[i]);
        if (space)
            Uart_Send_Byte(' '); //插入空格
    }
}
/*******************************************************************************
 * Function    : Uart_Send_Array2Ascii_R
 * Brief       : 
 * Parameter   : {u8*} data-待发送数组
 * Parameter   : {u8} len-数组长度
 * Parameter   : {u8} space-是否空格做间隔
 * Returns     : 
 * Date        : 2020-03-24 18:30:47
 * Description : 发送一个数组（转成ASCII），倒序
 ******************************************************************************/
void Uart_Send_Array2Ascii_R(u8 *data, u8 len, u8 space)
{
    u8 i;
    for (i = len; i != 0; i--)
    {
        Uart_Send_Byte2Ascii(data[i - 1]);
        if (space)
            Uart_Send_Byte(' '); //插入空格
    }
}
/*******************************************************************************
 * Function    : Uart_Send_String
 * Brief       : 
 * Parameter   : {u8*} data-字符串或数组
 * Returns     : {u8} len-长度
 * Date        : 2020-03-24 18:48:47
 * Description : 发送一个字符串或数组
 ******************************************************************************/
void Uart_Send_String(u8 *data, u8 len)
{
    u8 i;
    for (i = 0; i < len; i++)
    {
        txBuf[txCount] = *(data + i);
        txCount++;
        if (txCount >= MAX_SIZE)
            txCount = 0x00;
    }
}
/*******************************************************************************
 * Function    : Printf_OK
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 18:50:22
 * Description : 
 ******************************************************************************/
void Printf_OK(void)
{
    Uart_Send_String((u8 *)"\r\nIND:OK", 8);
}
/*******************************************************************************
 * Function    : Printf_Error
 * Brief       : 
 * Parameter   : {u8} Num-error of number
 * Returns     : 
 * Date        : 2020-03-24 18:50:59
 * Description : 
 ******************************************************************************/
void Printf_Error(u8 Num)
{
    Uart_Send_String((u8 *)"\r\nIND:Error(", 12);
    Uart_Send_Byte2Ascii(Num);
    Uart_Send_Byte(')');
}
/*******************************************************************************
 * Function    : GetUartTxFlag
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-25 15:16:44
 * Description : 获取串口发送状态
 ******************************************************************************/
u8 GetUartTxFlag(void)
{
    return txEn;
}
/*******************************************************************************
 * Function    : Uart_Send_Data
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 19:02:59
 * Description : 串口数据发送判断
 ******************************************************************************/
void Uart_Send_Data(void)
{
    if ((txLen != txCount) && (txEn == 0))
    {
        //有数据待发送，发送使能标志未置1
        txEn = 1;
        UART_InitStruct.Instance->SBUF = txBuf[txLen];
        txLen++;
        if (txLen >= MAX_SIZE)
            txLen = 0;
    }
}
/*******************************************************************************
 * Function    : Uart_Receive_Data
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 19:01:52
 * Description : 接收数据
 ******************************************************************************/
void Uart_Receive_Data(void)
{
    if (rxLen == rxCount)
    {
        rxTimeOut = 0x00;
        return; //没有接收到数据
    }
    if (rxTimeOut < 0x03) //5ms*3=15ms
    {
        rxTimeOut++;
        return; //接收的数据不完整
    }

    //接收到数据，提取
}
/*******************************************************************************
 * Function    : Fun_Uart_Run
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-03-24 19:02:19
 * Description : 串口执行
 ******************************************************************************/
void Fun_Uart_Run(void)
{
    Uart_Send_Data();
    Uart_Receive_Data();
}
